package com.megaspacevr.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.megaspacevr.entity.TimeSlots;
import com.megaspacevr.mapper.TimeSlotsMapper;
import com.megaspacevr.service.TimeSlotsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 时间段表-30分钟小场次 服务实现类
 * </p>
 *
 * @author yezi
 * @since 2025-06-17
 */
@Slf4j
@Service
public class TimeSlotsServiceImpl extends ServiceImpl<TimeSlotsMapper, TimeSlots> implements TimeSlotsService {

    @Override
    public List<TimeSlots> getTimeSlotsByDate(LocalDate date) {
        log.info("查询日期 {} 的时间段", date);
        
        QueryWrapper<TimeSlots> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("slot_date", date)
                   .eq("is_available", true)
                   .orderBy(true, true, "start_time");
        
        List<TimeSlots> timeSlots = list(queryWrapper);
        log.info("查询到 {} 个时间段", timeSlots.size());
        
        return timeSlots;
    }

    @Override
    public List<LocalDate> getAvailableDates() {
        log.info("获取所有可用日期");
        
        QueryWrapper<TimeSlots> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_available", true)
                   .ge("slot_date", LocalDate.now()) // 只查询今天及以后的日期
                   .select("DISTINCT slot_date");
        
        List<TimeSlots> timeSlots = list(queryWrapper);
        List<LocalDate> dates = timeSlots.stream()
                .map(TimeSlots::getSlotDate)
                .distinct()
                .sorted()
                .collect(Collectors.toList());
        
        log.info("获取到 {} 个可用日期", dates.size());
        return dates;
    }

    @Override
    @Transactional
    public boolean updateBookedCount(Long timeSlotId) {
        try {
            log.info("开始更新时间段预约人数，timeSlotId: {}", timeSlotId);
            
            // 获取当前时间段记录
            TimeSlots timeSlot = getById(timeSlotId);
            if (timeSlot == null) {
                log.error("时间段不存在，timeSlotId: {}", timeSlotId);
                return false;
            }
            
            // 更新预约人数
            int newBookedCount = timeSlot.getBookedCount() + 1;
            log.info("更新预约人数：原预约人数={}, 新预约人数={}", timeSlot.getBookedCount(), newBookedCount);
            
            // 只更新 booked_count 字段，避免与触发器冲突
            // 使用 UpdateWrapper 只更新需要的字段
            UpdateWrapper<TimeSlots> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", timeSlotId)
                        .set("booked_count", newBookedCount)
                        .set("updated_at", LocalDateTime.now());
            
            boolean result = this.update(updateWrapper);
            
            if (result) {
                log.info("时间段预约人数更新成功，timeSlotId: {}, 新预约人数: {}", timeSlotId, newBookedCount);
            } else {
                log.error("时间段预约人数更新失败，timeSlotId: {}", timeSlotId);
            }
            
            return result;
        } catch (Exception e) {
            log.error("更新时间段预约人数时发生异常，timeSlotId: {}", timeSlotId, e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean decreaseBookedCount(Long timeSlotId) {
        try {
            log.info("开始减少时间段预约人数，timeSlotId: {}", timeSlotId);
            
            // 获取当前时间段记录
            TimeSlots timeSlot = getById(timeSlotId);
            if (timeSlot == null) {
                log.error("时间段不存在，timeSlotId: {}", timeSlotId);
                return false;
            }
            
            // 减少预约人数，但不能小于0
            int newBookedCount = Math.max(0, timeSlot.getBookedCount() - 1);
            log.info("减少预约人数：原预约人数={}, 新预约人数={}", timeSlot.getBookedCount(), newBookedCount);
            
            // 使用 UpdateWrapper 只更新需要的字段
            UpdateWrapper<TimeSlots> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", timeSlotId)
                        .set("booked_count", newBookedCount)
                        .set("is_locked", false) // 取消锁定状态
                        .set("updated_at", LocalDateTime.now());
            
            boolean result = this.update(updateWrapper);
            
            if (result) {
                log.info("时间段预约人数减少成功，timeSlotId: {}, 新预约人数: {}", timeSlotId, newBookedCount);
            } else {
                log.error("时间段预约人数减少失败，timeSlotId: {}", timeSlotId);
            }
            
            return result;
        } catch (Exception e) {
            log.error("减少时间段预约人数时发生异常，timeSlotId: {}", timeSlotId, e);
            return false;
        }
    }
}
